import axios from 'axios';
import { random, toInteger } from 'lodash'

const instance = axios.create({

});

instance.interceptors.response.use(resp => {
    return resp;
}, err => {
    const { config, response } = err;
    const errStatus = {
        '418': true,
        '401': true,
    }
    // 检查是否是状态码 429 错误
    if (response && response.status === 429) {
        const s = random(20, 30);
        console.log(`请求被限流，${s}秒后重试`);
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve(instance(config));
            }, s * 1000);
        });
    } else if (response && errStatus[response.status]) {
        const s = random(60, 180);
        console.log(`请求被察觉异常，${s}秒后重试`);
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve(instance(config));
            }, s * 1000);
        });
    }

    // 如果不是 429 错误，或者已经超过了重试次数，则抛出错误
    return Promise.reject(err);
})

/**
 * 学习某个任务
 * 可用任务类型：观看页面|
 * @param {number} activityId
 * @param {any} body 视频任务需传start、end
 */
const postActivitiesRead = async (activityId, body = {}) => {
    const url = `https://lms.ouchn.cn/api/course/activities-read/${activityId}`

    try {
        const res = await instance.request({
            url,
            method: 'POST',
            data: body
        });

        if (res.status === 201) {
            return res.data;
        } else {
            throw new Error(`学习任务失败: ${activityId}`)
        }
    } catch (error) {
        throw error;
    }
}

const getDoneActivities = async (courseId) => {
    const url = `https://lms.ouchn.cn/api/course/${courseId}/activity-reads-for-user`;

    try {
        const res = await instance.request({
            url,
            method: 'GET'
        });

        if (res.status === 200) {
            return res.data.activity_reads.map(item => {
                if (item.completeness !== "part") return item.activity_id
            })
        } else {
            throw new Error('获取已学习任务失败');
        }
    } catch (error) {
        throw error;
    }
}


const useGlobalData = () => {
    return globalThis.globalData;
}

const postOnelineVideos = async ({ module_id, activity_id, upload_id, syllabus_id, duration }) => {
    const globalData = useGlobalData();
    duration = toInteger(duration);
    const url = `https://lms.ouchn.cn/statistics/api/online-videos`;
    const onlineVideosBody = {
        "user_id": globalData.user.id,
        "org_id": globalData.user.orgId,
        "course_id": globalData.course.id,
        "module_id": module_id,
        "syllabus_id": syllabus_id,
        "activity_id": activity_id,
        "upload_id": upload_id,
        "reply_id": null,
        "comment_id": null,
        "forum_type": "",
        "action_type": "play",
        "is_teacher": false,
        "is_student": true,
        "is_final": null,
        "is_formative": null,
        "ts": Date.now(),
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5666.197 Safari/537.36",
        "meeting_type": "online_video",
        "master_course_id": document.querySelector("#masterCourseId").value,
        "org_name": globalData.user.orgName,
        "org_code": globalData.user.orgCode,
        "user_no": globalData.user.userNo,
        "user_name": globalData.user.name,
        "course_code": globalData.course.courseCode,
        "course_name": globalData.course.name,
        "dep_id": globalData.dept.id,
        "dep_name": globalData.dept.name,
        "dep_code": globalData.dept.code
    }

    for (const type of ['view', 'play']) {
        onlineVideosBody.action_type = type;
        if (type === 'play') {
            onlineVideosBody["start_at"] = 0
            onlineVideosBody["end_at"] = duration
            onlineVideosBody["duration"] = duration
        }
        try {
            const res = await instance.request({
                url,
                method: "POST",
                data: onlineVideosBody
            })

            if (res.status === 204) {

            } else {
                throw new Error('伪造音视频观看记录失败！')
            }
        } catch (error) {
            throw error;
        }
    }
}

// const postLearningActivity = async ({ module_id, activity_id, upload_id, syllabus_id, duration }) => {
//     const globalData = useGlobalData();
//     duration = toInteger(duration);
//     const url = `https://lms.ouchn.cn/statistics/api/learning-activity`;
//     const onlineVideosBody = {
//         "user_id": globalData.user.id,
//         "org_id": globalData.user.orgId,
//         "course_id": globalData.course.id,
//         "module_id": module_id,
//         "syllabus_id": syllabus_id,
//         "activity_id": activity_id,
//         "upload_id": upload_id,
//         "reply_id": null,
//         "comment_id": null,
//         "forum_type": "",
//         "action": "open",
//         "is_teacher": false,
//         "is_student": true,
//         "ts": Date.now(),
//         "user_agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5666.197 Safari/537.36",
//         "meeting_type": "online_video",
//         "master_course_id": document.querySelector("#masterCourseId").value,
//         "org_name": globalData.user.orgName,
//         "org_code": globalData.user.orgCode,
//         "user_no": globalData.user.userNo,
//         "user_name": globalData.user.name,
//         "course_code": globalData.course.courseCode,
//         "course_name": globalData.course.name,
//         "dep_id": globalData.dept.id,
//         "dep_name": globalData.dept.name,
//         "dep_code": globalData.dept.code,
//         "activity_name": null,
//         "activity_type": "online_video",
//         "channel": "web",
//         "enrollment_role": "student",
//         "mode": "normal",
//         "module": null,

//     }

//     try {
//         const res = await instance.request({
//             url,
//             method: "POST",
//             data: onlineVideosBody
//         })

//         if (res.status === 204) {

//         } else {
//             throw new Error('伪造音视频观看记录失败！')
//         }
//     } catch (error) {
//         throw error;
//     }
// }

// 学习视频内容
const learnVideo = async (courseId, id, uploads = [], params) => {

    if (uploads.length > 0) {
        for (const upload of uploads) {
            for (const video of upload.videos) {
                const { duration } = video;
                const start = 0;
                const end = duration;
                const body = {
                    start,
                    end
                }
                await postActivitiesRead(id, body);
                await postOnelineVideos({
                    ...params,
                    duration,
                    upload_id: video.id,
                });
                await sleep(random(5, 8) * 1000);
            }
            console.log('音视频学习任务完成', upload.id);
            await sleep(random(5, 8) * 1000);
        }
        console.log('该任务下所有音视频学习任务完成', uploads);
    }
}

// 学习观看页面
const learnViewPage = async (courseId, learnId, uploads = []) => {
    await postActivitiesRead(learnId);
    console.log('观看页面任务完成', learnId);

    if (uploads.length > 0) {
        for (const upload of uploads) {
            await postActivitiesRead(learnId, { upload_id: upload.id });
        }
        console.log('附件学习任务完成', uploads);
    }
}

// 学习发帖回帖模块
const learnForum = async (courseId, id) => {
    const getForumTopicId = async () => {
        const url = 'https://lms.ouchn.cn/api/activities/' + id;
        try {
            const res = await instance.request({
                url,
                method: 'GET'
            })

            if (res.status === 200) {
                return res.data.topic_category_id
            } else {
                throw new Error('获取任务详情信息失败！')
            }
        } catch (error) {

        }
    }
    const addTopic = async (topicId) => {
        const body = {
            category_id: topicId,
            content: '好好学习，天天向上' + Date.now(),
            title: '好好学习' + Date.now(),
            uploads: []
        }
        const url = 'https://lms.ouchn.cn/api/topics';

        try {
            const res = await instance.request({
                url,
                method: 'POST',
                data: body
            })

            if (res.status === 201) {
                return res.data.id;
            }
        } catch (error) {
            throw error;
        }
    }

    const addReply = async (topicId) => {
        const body = {
            content: '好好学习，天天向上' + Date.now(),
            uploads: []
        }
        const url = `https://lms.ouchn.cn/api/topics/${topicId}/replies`;

        try {
            const res = await instance.request({
                url,
                method: 'POST',
                data: body
            })

            if (res.status === 200) {
                return res.data;
            } else {
                throw new Error('回复失败');
            }
        } catch (error) {
            throw error;
        }
    }
    try {
        const topicId = await addTopic(await getForumTopicId());
        await addReply(topicId);
        console.log('发帖回帖任务完成', topicId);
    } catch (error) {
        if (error.response.status === 403 && error.response.data.message === '限制学生发帖')
            console.log('无需发帖', id);
    }



}



/**
 * 获取某课程所有学习任务
 * @param {number} courseId
 */
const getAllActives = async (courseId) => {
    /**
     * 获取课程任务专栏模块
     */
    const getModules = async () => {
        const url = `https://lms.ouchn.cn/api/courses/${courseId}/modules`;

        try {
            const res = await instance.request({
                url,
                method: 'GET'
            });

            if (res.status === 200) {
                return res.data.modules.map(item => {
                    return item.id;
                })
            } else {
                throw new Error('获取modules失败')
            }
        } catch (error) {
            throw error;
        }
    }

    const modules = await getModules();
    const url = `https://lms.ouchn.cn/api/course/${courseId}/all-activities`
    const params = {
        module_ids: `[${modules.join(',')}]`,
        activity_types: "learning_activities,exams,classrooms,live_records,rollcalls"
    }

    try {
        const res = await instance.request({
            url,
            method: 'GET',
            params
        });

        if (res.status === 200) {
            const { learning_activities } = res.data;
            return learning_activities.map(item => {
                return {
                    type: item.type,
                    activity_id: item.id,
                    typeName: item.completion_criterion,
                    // 如果该值 = []代表无需学习该附件
                    uploads: item.uploads,
                    module_id: item.module_id,
                    course_id: item.course_id,
                    syllabus_id: item.syllabus_id
                }
            });
        } else {
            throw new Error('获取所有任务失败')
        }
    } catch (error) {
        throw error;
    }
}


const sleep = (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

globalThis.learnTech = async () => {
    console.clear()

    const globalData = useGlobalData();
    const courseId = globalData.course.id;

    const activities = await getAllActives(courseId);
    let doneActivities = await getDoneActivities(courseId);
    console.log(activities)
    console.log(doneActivities)
    for (let i = 0; i < activities.length; i++) {
        const { type, activity_id, uploads, typeName } = activities[i];

        if (doneActivities.includes(activity_id)) {
            console.log('已学习，跳过', activity_id);
            continue;
        } else {
            console.log('未学习，开始学习', activity_id);
            await postActivitiesRead(activity_id);
        }

        switch (type) {
            case 'page':
                await learnViewPage(courseId, activity_id);
                break;
            case 'forum':
                await learnForum(courseId, activity_id);
                break;
            case 'material':
                await learnViewPage(courseId, activity_id, uploads);
                break;
            case 'online_video':
                await learnVideo(courseId, activity_id, uploads, activities[i]);
                break;
            default:
                console.log('未实现', type);
                continue;
        }

        const s = random(5, 15);
        console.log(`学习完成，休息${s}秒`);
        await sleep(s * 1000);

    }

    console.log('学习完成');
}

